package com.zk.iotgateway.net.common;

import com.zk.iotgateway.bizhandler.IHandler;
import com.zk.iotgateway.domain.param.IotConfigDO;
import com.zk.iotgateway.manager.GlobalManager;
import com.zk.iotgateway.constant.Loggers;
import com.zk.iotgateway.domain.locator.LocatorDO;
import com.zk.iotgateway.service.IotConfigService;
import com.zk.iotgateway.util.NettyUtil;
import com.zk.iotgateway.util.SpringUtil;
import com.zk.iotgateway.util.StringUtils;
import io.netty.channel.*;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

/**
 * 处理器
 *  相关业务逻辑处理
 *
 * @author:mn.m
 * @create 2019-07-03 上午 09:32
 **/

@Component
@ChannelHandler.Sharable
public class IotCommonHandler extends ChannelInboundHandlerAdapter {

    @Autowired
    private IotConfigService iotConfigService;
    private IHandler iHandler;

    private final Logger logger = Loggers.serverLogger;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        Channel channel = ctx.channel();
        InetSocketAddress insocket = (InetSocketAddress)channel.remoteAddress();
        String ipAddress = StringUtils.formatIpAddress(insocket.getHostName(), String.valueOf(insocket.getPort()));
        String clientIpAddress = ipAddress;
        logger.info("线上---------"+ipAddress);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        Channel channel = ctx.channel();
        GlobalManager.DEVMANAGER.remove(channel);
        InetSocketAddress insocket = (InetSocketAddress)channel.remoteAddress();
        logger.info("下线了-------"+insocket.getAddress()+insocket.getPort());

    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            IotConfigDO configByPort = iotConfigService.findConfigByPort(NettyUtil.returnPort(ctx));
            if (configByPort!= null){
                String beanName = StringUtils.getBeanName(configByPort.getHandler());
                iHandler = (IHandler) SpringUtil.getBean(beanName);
                iHandler.handle(ctx,msg);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // TODO Auto-generated method stub
        super.exceptionCaught(ctx, cause);
        /**
         * 发生异常时删除缓存中对应的client的缓存
         */
        Channel channel = ctx.channel();
        GlobalManager.DEVMANAGER.remove(channel);
        InetSocketAddress insocket = (InetSocketAddress)channel.remoteAddress();
        String ipAddress = StringUtils.formatIpAddress(insocket.getHostName(), String.valueOf(insocket.getPort()));
        logger.info("异常ip------"+ipAddress);
        cause.printStackTrace();
    }
    /**
     * 心跳检测触发的事件通过本方法捕获
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            System.out.println("心跳检测开始");
            IdleState state = ((IdleStateEvent) evt).state();
            if(state == state.READER_IDLE ){
                ChannelFuture fcutrue =  ctx.close();
                fcutrue.addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        Channel channel = future.channel();
                        GlobalManager.DEVMANAGER.remove(channel);
                        InetSocketAddress insocket = (InetSocketAddress)channel.remoteAddress();
                        String ipAddress = StringUtils.formatIpAddress(insocket.getHostName(), String.valueOf(insocket.getPort()));
                        System.out.println(ipAddress+"心跳超时下线成功....");
                    }
                });
            }
        }else{
            super.userEventTriggered(ctx, evt);
        }

    }
}
